<?php
declare(strict_types=1);

namespace App\Service;

use App\Helper\Log;
use App\Helper\Util;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\ApplicationContext;

/**
 * 统计服务
 */
class StatisrecService 
{
    private $tags = [];
    /**
     * [__construct description] 构造函数
     */
    public function __construct()
    {
        $this->initTags();
    }
    /**
     * 入口
     * [doSave description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function doSave($params)
    {
        if(empty($params['save_type'])){
            return false;
        }
        switch ($params['save_type']) {
            case 'normal':
                $res = $this->saveRecord($params);
                return $res;
                break;
            case 'norepeat':
                if(empty($params['user_id'])){
                    return false;
                }
                $container = ApplicationContext::getContainer();
                $redis = $container->get(\Redis::class);
                $norepeat_redis_key = "spb_static_repeat:".date("Y-m-d");

                $norepeat_redis_tag = "user_".$params['user_id']."_".$params['tag'];
                if(!empty($params['id'])){
                    $norepeat_redis_tag .= "_".$params['id'];
                }
                if ($redis->HEXISTS($norepeat_redis_key, $norepeat_redis_tag)) {
                    return false;
                }
                $redis->HSET($norepeat_redis_key, $norepeat_redis_tag, "1");
                $redis->EXPIRE($norepeat_redis_key, 86400);
                //统计
                $res = $this->saveRecord($params);
                return $res;
                break;
        }
        return true;
    }
    /**
     * 保存记录
     * [saveRecord description]
     * @param  [type] $params [description]
     * tag [必传项] 统计标识
     * terminal [必传项] 设备类型：h5、ios、android
     * @return [type]         [description]
     */
    public function saveRecord($params)
    {
        if(empty($params['tag']) || empty($params['device'])){
            return false;
        }
        if(!array_key_exists($params['tag'], $this->tags)){
            return false;
        }
        $tag_info = $this->tags[$params['tag']];
        $params['type'] = $tag_info['type'];
        switch ($tag_info['type']) {
            case 'statis':
            case 'share':
            case 'hit':
            case 'everyday':
                $this->saveHitType($params);
                break;
        }
        return true;
    }
    /**
     * 保存点击类型
     * [saveHitType description]
     * @param  [type] $params [description]
     * @return [type]         [description]
     */
    public function saveHitType($params)
    {
        $date = date("Y-m-d");
        //点击次数固定1次，不可自定义
        $params['num'] = 1;
        //点击类型的点击量不能都为空
        if(empty($params['num'])){
            return false;
        }
        /*数据*/
        $exists = $this->getRecord($params['tag'], $date);
        if(empty($exists)){
            $insert_data = [
                'tag' => $params['tag'],
                'type' => $params['type'],
                'date' => $date,
                'created_at' => time(),
            ];
            $insert_data = $this->getNeedSaveOp($insert_data, $params);
            $res = Db::table('statis_record')
                ->insert($insert_data);
        }else{
            $update_data = $this->getNeedSaveOp([], $params, $exists);
            $res = Db::table('statis_record')
                ->where("id", $exists['id'])
                ->update($update_data);
        }
        return $res;
    }
    /**
     * 获取单条记录
     * [getRecord description]
     * @param  [type] $tag  [description]
     * @param  [type] $type [description]
     * @param  [type] $date [description]
     * @return [type]       [description]
     */
    public function getRecord($tag, $date)
    {
        $data_info = Db::table('statis_record')
            ->select(['id','tag','type','date','num','h5_num','applet_num','android_num','ios_num'])
            ->where(['tag'=>$tag,'date'=>$date])
            ->first();
        return $data_info;
    }
    /**
     * 组合更新数据
     * [getNeedSaveOp description]
     * @param  [type] $data   [description]
     * @param  [type] $params [description]
     * @param  [type] $exists [description]
     * @return [type]         [description]
     */
    public function getNeedSaveOp($data, $params, $exists=[])
    {
        switch ($params['device']) {
            case 'wechat':
                if(!empty($exists)){
                    $data['num'] = $exists['num']+$params['num'];
                    $data['h5_num'] = $exists['h5_num']+$params['num'];
                }else{
                    $data['num'] = $params['num'];
                    $data['h5_num'] = $params['num'];
                }
                break;
            case 'applet':
                if(!empty($exists)){
                    $data['num'] = $exists['num']+$params['num'];
                    $data['applet_num'] = $exists['applet_num']+$params['num'];
                }else{
                    $data['num'] = $params['num'];
                    $data['applet_num'] = $params['num'];
                }
                break;
            case 'ios':
                if(!empty($exists)){
                    $data['num'] = $exists['num']+$params['num'];
                    $data['ios_num'] = $exists['ios_num']+$params['num'];
                }else{
                    $data['num'] = $params['num'];
                    $data['ios_num'] = $params['num'];
                }
                break;
            case 'android':
                if(!empty($exists)){
                    $data['num'] = $exists['num']+$params['num'];
                    $data['android_num'] = $exists['android_num']+$params['num'];
                }else{
                    $data['num'] = $params['num'];
                    $data['android_num'] = $params['num'];
                }
                break;
        }
        return $data;
    }
    /**
     * 初始化标签
     * [initTags description]
     * @return [type] [description]
     */
    private function initTags()
    {
        $tags = Db::table('statis_tags')
            ->select(['name','tag','type'])
            ->where(['is_del'=>0,'status'=>1])
            ->get()
            ->toArray();
        if(!empty($tags)){
            $this->tags = array_column($tags, NULL, "tag");
        }
    }
}
